var Foo; // a simple stack class

Foo || (function(global,    // @param Global: as global or window
                 document,  // @param DocumentObject: as window.document
                 modules) { // @param Boolean: true is module ready(as Common.js)

//{@ss
if (modules) {
    module.exports = {
        Foo: Foo
    };
}
//}@ss

// build and export api
function _api() {
    global.Foo = Foo;   // new global.Foo(initial-stack-data, ...)
}

// --- local vars ---
// none

// --- impl ---
function Foo(/* var_args */) { // @param Mix: values
                               // @help: Foo#Foo
                               // @desc: init stack
    this._ary = [].slice.call(arguments);
    this.init();
}
Foo.prototype = {
    init:       Foo_init,
    top:        Foo_top,    // Foo#top()
    size:       Foo_size,   // Foo#size()
    push:       Foo_push,   // Foo#push()
    pop:        Foo_pop,    // Foo#pop()
    clear:      Foo_clear,  // Foo#clear()
    isEmpty:    Foo_isEmpty // Foo#empty()
};

// new Foo()
function Foo_init() {
    // nop
}

// Foo#top
function Foo_top() { // @return Mix: data or undefined
                     // @help: Foo#Foo.top
                     // @desc: get top data
    return this._ary[this._ary.length - 1];
}

// Foo#size
function Foo_size() { // @return Number: data length
                      // @help: Foo#Foo.size
                      // @desc: get stack size
    return this._ary.length;
}

// Foo#push
function Foo_push(data) { // @param Mix: data
                          // @return Mix: data
                          // @help: Foo#Foo.push
                          // @desc: push data
    this._ary.push(data);
    return data;
}

// Foo#pop
function Foo_pop() { // @return Mix: poped data
                     //              or undefined
                     // @help: Foo#Foo.pop
                     // @desc: pop
    return this._ary.pop();
}

// Foo.clear
function Foo_clear() { // @return Mix: poped data or undefined
                       // @help: Foo#Foo.pop
                       // @desc: pop

    var rv = this._ary.concat(); // copy

    this._ary.length = 0;
    return rv;
}

// Foo.isEmpty
function Foo_isEmpty() { // @return Boolean: true is empty data
                         // @help: Foo#Foo.empty
                         // @desc: is empty
    return !this._ary.length;
}

// --- build and export api ---
modules || _api();

})(this.self || global,
   this.document,
   typeof module !== "undefined");

